#ifndef __JSBSIM_H__
#define __JSBSIM_H__

#include <stdio.h>
#include <stdlib.h>

#include <string>
#include <deque>

#include "base/osa/osa++.h"
#include "base/utils/utils_misc.h"
#include "network/Socket++.h"


namespace pi {


////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

class JSBSim : public RThread
{
public:
    JSBSim() { init(); }
    virtual ~JSBSim() { release(); }

    int runJSBSim(void);
    int openInputSocket(void);
    int openOutputSocket(void);

    int run(void);
    int stop(void);

    int sendMsg(const std::string &msg);
    int recvMsg(std::string &msg);
    int recvData(std::vector<double> &dat);
    int pushMsg(const std::string &msg);
    int popMsg(std::string &msg);

    virtual int thread_func(void *arg);

    int init(void);
    int release(void);

public:
    std::string         m_jsbRootDir;
    std::string         m_jsbOptions;
    std::string         m_jsbScript;

    std::string         m_addr;
    int                 m_jsbIn_port, m_jsbOut_port;

    ExecProgram         m_jsbExe;
    RSocket             m_socketIn,
                        m_socketOut, m_socketOutRecv;

    RMutex              m_mutexRecv;
    int                 m_isRunning;

    std::deque<std::string>     m_msgBuff;
};


////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
enum JSBSIM_DataIndex
{
    // time
    JSBSIM_DAT_TIME                 = 0,

    // aerosurfaces
    JSBSIM_DAT_AILERON_CMD,
    JSBSIM_DAT_ELEVATOR_CMD,
    JSBSIM_DAT_RUDDER_CMD,
    JSBSIM_DAT_FLAP_CMD,
    JSBSIM_DAT_LEFT_AILERON_POSITION,
    JSBSIM_DAT_RIGHT_AILERON_POSITION,
    JSBSIM_DAT_ELEVATOR_POSITION,
    JSBSIM_DAT_RUDDER_POSITION,
    JSBSIM_DAT_FLAP_POSITION,

    // velocities
    JSBSIM_DAT_SPD_QBAR,
    JSBSIM_DAT_SPD_VTOTAL,
    JSBSIM_DAT_SPD_UBODY,
    JSBSIM_DAT_SPD_VBODY,
    JSBSIM_DAT_SPD_WBODY,
    JSBSIM_DAT_SPD_UAERO,
    JSBSIM_DAT_SPD_VAERO,
    JSBSIM_DAT_SPD_WAERO,
    JSBSIM_DAT_SPD_VN,
    JSBSIM_DAT_SPD_VE,
    JSBSIM_DAT_SPD_VD,

    // position
    JSBSIM_DAT_ALTITUDE,
    JSBSIM_DAT_PHI,                                 // roll
    JSBSIM_DAT_THT,                                 // pitch
    JSBSIM_DAT_PSI,                                 // yaw
    JSBSIM_DAT_ALPHA,
    JSBSIM_DAT_BETA,
    JSBSIM_DAT_LATITUDE,
    JSBSIM_DAT_LONGITUDE,
};


} // end of namespace pi

#endif // end of __JSBSIM_H__
